<template>
  <div
    class="ek-list"
    :class="{ 'is-tree-on': configs.treeOn }"
    ref="contanier"
  >
    <!-- 左边树部分 -->
    <div class="ek-list-left" v-if="configs.treeOn">
      <ekListTree :config="trees" @node-click="handleNodeClick"></ekListTree>
    </div>
    <!-- 右边部分 -->
    <div class="ek-list-right">
      <!-- 表格搜索区域 -->
      <div class="ek-list-search" ref="search" v-if="configs.searchOn">
        <ekSearch
          :params="searchs"
          @search="handleSearch"
          :size="size"
        ></ekSearch>
      </div>
      <!-- 表格内容区域 -->
      <div class="ek-list-content">
        <ekTable
          :maxHeight="height"
          :columns="columns"
          :buttons="buttons"
          :tableData="tableData"
          :configs="configs"
          :reserveSelection="
            configs.treePropsOn ? false : configs.reserveSelection
          "
          :defaultExpandAll="configs.defaultExpandAll"
          :ekDialog="configs.ekDialog"
          @sort-change="handleSortChange"
          @refresh="handleRefresh"
          @operateCallback="handleOperate"
          :loading="loading"
          ref="refTable"
          :size="size"
          @cell-click="handleCellClick"
          :expandRowKeys="expandRowKeys"
        >
          <template #operate>
            <slot name="operate"></slot>
          </template>
          <template #operateColumn="{ scope, item }">
            <slot name="operateColumn" :scope="scope" :item="item"></slot>
          </template>
          <template v-for="detail in columns" #[detail.slot]="{ scope, item }">
            <slot
              :name="detail.slot"
              :scope="scope"
              :item="item"
              v-if="detail.slot"
            ></slot>
          </template>
        </ekTable>
      </div>
      <!-- 表格分页区域 -->
      <div class="ek-list-page" ref="page" v-if="configs.pageOn">
        <ekPagination
          v-model:currentPage="tablePage.currentPage"
          v-model:pageSize="tablePage.pageSize"
          :total="tablePage.total"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :size="size"
        >
        </ekPagination>
      </div>
    </div>
  </div>
</template>

<script setup>
import {
  defineComponent,
  onMounted,
  getCurrentInstance,
  ref,
  reactive,
  computed,
} from "vue";

import { useStore } from "vuex";
import { useRouter } from "vue-router";
// 组件
import ekTable from "@/components/business/ekTable";
import ekSearch from "@/components/business/ekSearch";
import ekPagination from "@/components/business/ekPagination/index.vue";
import ekListTree from "@/components/business/ekList/components/ekListTree.vue";

import queryBulider from "@/utils/queryBulider";
import { arrayToTree } from "@/utils/common";

// 入参
const props = defineProps({
  // 配置json
  layoutData: {
    type: Object,
    default: () => {
      return {};
    },
  },
  size: {
    type: String,
    default: "default",
  },
});
const emit = defineEmits(["size-change", "cell-click"]);

const {
  appContext: {
    config: { globalProperties },
  },
  proxy: { $nextTick },
} = getCurrentInstance();

const store = useStore();
const router = useRouter();
const { $storage, $http } = globalProperties;

// 展开行数据
const expandRowKeys = ref([]);
/* 获取配置 */
// 获取配置
let configs = computed(() => {
  return {
    // 开启分页默认true(是否启用分页)
    pageOn: true,
    // 开启搜索默认true
    searchOn: true,
    // 开启操作区域默认true
    operateOn: false,
    // 开启左边树 默认false
    treeOn: false,
    // 表格是否启用树模式
    treePropsOn: false,
    // 保持选中行
    reserveSelection: false,
    // 展开树结构
    defaultExpandAll: false,
    // 默认列表地址
    ...props.layoutData.configs,
  };
});

/* 左边树部分 */
// 左边树配置
let trees = computed(() => {
  return props.layoutData.trees || {};
});
// 左边树， 查询条件映射
let treeSearchMapping = computed(() => {
  return trees.value.searchMapping || [];
});

// 左边树查询条件
let treeSearchParam = [];

/* 左边树部分结束 */

// 获取查询区域配置
let searchs = computed(() => {
  return props.layoutData.searchs;
});

const listUrl = computed(() => {
  return (
    configs.value.listUrl ||
    `/admin/basis/getList?modelCode=${props.layoutData.modelCode}`
  );
});
// 获取表格显示字段
let columns = computed(() => {
  return props.layoutData.columns || [];
});
// 获取配置按钮区域
let buttons = computed(() => {
  return props.layoutData.buttons || [];
});
// 获取分页数据
let pages = computed(() => {
  return {
    pageSize: 20,
    orders: [],
    defaultSearchParam: [], // 默认查询条件
    ...props.layoutData.pages,
  };
});
/* 表格加载中 */
let loading = ref(false);

/* 分页区域 */
let tablePage = computed(() => {
  return {
    currentPage: 1, // 当前页
    pageSize: pages.value.pageSize, // 每页显示条数
    total: 0, // 总条数
    searchParam: [], // 查询条件数据对象
    orders: pages.value.orders, // 排序
  };
});

/* 表格数据 */
let tableData = ref([]);
let originData = ref([]);
// 初始化表格
function initTable() {
  tablePage.value.currentPage = 1;
  tablePage.value.searchParam = [];
}
// 获取表格数据 isLoading 是否开启loading加载数据
function getData(isLoading = true, done) {
  loading.value = isLoading;
  // 构建查询条件
  let searchParam = queryBulider.insertArrayBetween(
    [...tablePage.value.searchParam],
    { logic: "and", type: "logic" }
  );
  if (treeSearchParam.length) {
    if (searchParam.length) {
      searchParam.push({ logic: "and", type: "logic" });
    }
    searchParam = searchParam.concat(treeSearchParam);
  }
  if (pages.value.defaultSearchParam.length) {
    if (searchParam.length) {
      searchParam.push({ logic: "and", type: "logic" });
    }
    searchParam = searchParam.concat(pages.value.defaultSearchParam);
  }

  $http
    .post(listUrl.value, {
      // 是否开启分页，不开启分页则取全部数据，分页界面区域不显示（开启树型时候是否强制不开启分页呢）
      pageOn: configs.value.pageOn ? 1 : 0,
      currentPage: tablePage.value.currentPage,
      pageSize: tablePage.value.pageSize,
      orders: tablePage.value.orders,
      search: {
        ...searchParam,
      },
    })
    .then((res) => {
      if (res.status === "success") {
        if (configs.value.treePropsOn) {
          originData.value = res.data.list;
          let tree = arrayToTree(res.data.list);
          tableData.value = tree;
        } else {
          originData.value = res.data.list;
          tableData.value = res.data.list;
          tablePage.value.total = res.data.total;
        }
      }
    })
    .finally(() => {
      // setTimeout(() => {
      loading.value = false;
      done && done(); // 目前只有刷新使用
      // }, 500);
    });
}

/**表格高度计算 */
const contanier = ref(null);
const search = ref(null);
const page = ref(null);
let height = ref(0);
$nextTick(() => {
  height = computed({
    get() {
      let contanierHeight = contanier.value.offsetHeight; // 整个容器高度
      let searchHeight = search.value ? search.value.offsetHeight : 0; //查询区域高度,
      let pageHeight = page.value ? page.value.offsetHeight : 0; //分页高度
      // let operateHeight = configs.value.operateOn ? (props.size === 'small' ? 40 : 48) : 0; // 操作区域高度
      let operateHeight = props.size === "small" ? 40 : 48;
      // 48 操作区高度 ， 16是table-content padding上下和
      return contanierHeight - searchHeight - pageHeight - operateHeight - 16;
    },
  });
});
// 分页页数改变
function handleSizeChange(event) {
  initTable();
  tablePage.value.pageSize = event;
  getData();
  emit("size-change", event);
}
// 分页页当前页改变
function handleCurrentChange(event) {
  console.log("current-change", event);
  tablePage.value.currentPage = event;
  getData();
}
// 按钮操作完毕后回调，无刷感修改数据
function handleOperate() {
  // initTable();
  getData(false);
}
// 点击排序
function handleSortChange({ column, prop, order }) {
  initTable();
  tablePage.value.orders = [
    {
      field: prop,
      sort: order == "descending" ? "desc" : "asc",
    },
  ];

  getData();
}
// 点击刷新
function handleRefresh(done) {
  initTable();
  getData(true, done);
}
// 点击查询按钮
function handleSearch(event) {
  initTable();
  tablePage.value.searchParam = event;
  getData();
}
// 单元格点击
function handleCellClick(row, column, cell, event) {
  emit("cell-click", row, column, cell, event);
}

// 初始化
function init() {
  initTable();
  getData();
}

// 获取所有选中的行
let refTable = ref(null);
function getSelectionRows() {
  return refTable.value.getSelectionRows();
}
function getCurrentRow() {
  return refTable.value.getCurrentRow();
}
// 获取左边树选中节点
function getTreeNode() {
  return treeSelectNode.value;
}
function refresh() {
  initTable();
  getData();
}
/* 左边树部分 */
// 左边树选中的节点
const treeSelectNode = ref("");
// 左边列表点击后触发事件， 添加查询条件并刷新表格，还要考虑初始化处理？
function handleNodeClick(node) {
  treeSelectNode.value = node;
  treeSearchParam = queryBulider.build(treeSearchMapping.value, node);
  initTable();
  getData();
}
/* 左边树部分结束 */

// 展开所有
function expandAll() {
  expandRowKeys.value = originData.value.map((item) => item.id);
}
// 收起所有
function collapseAll() {
  expandRowKeys.value = [];
}
onMounted(() => {
  init();
});
// 暴露给外部的方法
defineExpose({
  getSelectionRows,
  getCurrentRow,
  refresh,
  expandAll,
  collapseAll,
});
</script>

<style scoped lang="scss">
.ek-list {
  height: 100%;
  display: flex;
  &.is-tree-on {
    > .ek-list-right {
      width: calc(100% - 226px);
    }
  }
  > .ek-list-left {
    width: 200px;
    background-color: #fff;
    margin-right: 10px;
    padding: 8px;
    border-radius: var(--base-border-radius);
    height: calc(100% - 16px);
    overflow: auto;
  }
  > .ek-list-right {
    width: 100%;
    .ek-list-search {
      background-color: #fff;
      padding: 8px;
      border-radius: var(--base-border-radius) var(--base-border-radius) 0 0;
      border-bottom: 1px solid #eee;
    }

    .ek-list-content {
      background-color: #fff;
      padding: 8px;
      border-radius: 0 0 var(--base-border-radius) var(--base-border-radius);
    }
    .ek-list-page {
      background-color: #fff;
      padding: 0 8px 8px 8px;
      display: flex;
      justify-content: flex-end;
    }
  }
}
</style>
